package yxk.task.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.wtc.wtis.webapi.punchcard.model.PunchCardReqMode;
import kd.wtc.wtis.webapi.punchcard.validate.ListValidator;
import yxk.utils.DateUtil;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lijiawang
 * @Date 2023/9/12 14:27
 * @Description:获取海康威和飞书的请求接口方法;
 */
public class PunchcardDataUtil {
    private RequesUtil requesUtil=new RequesUtil();
    private static final Log LOG = LogFactory.getLog(PunchcardDataUtil.class);
     /**
     *    海康打卡数据同步
     * @param startStr  开始时间
     * @param endStr    结束时间
     * @return
     */
    public List<ListValidator<PunchCardReqMode>> getHAIKANPunchcardObtainList(String startStr,String endStr,String receiveStartTime,String receiveEndTime){
        List<JSONArray> requestJson = requesUtil.getHKClockRequest(startStr, endStr, receiveStartTime, receiveEndTime);
        LOG.info("RequesUtil.getHAIKANPunchcardObtainList.requestJson:{}",requestJson);
        List<ListValidator<PunchCardReqMode>> list=new ArrayList<>();
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat hms=new SimpleDateFormat("HH:mm:ss");

        //收集工号集合 防止过多访问数据库
        List<String> numbers=new ArrayList<>();
        for (JSONArray array : requestJson) {
            for (int i = 0; i <array.size(); i++) {
                JSONObject rowMap = array.getJSONObject(i);
                String cardNo = rowMap.getString("jobNo");
                if(cardNo == null){
                    continue;
                }
                numbers.add(cardNo);
            }
        }
        //根据工号查询考勤数据库数据
        QFilter attQF = new QFilter("attperson.number", QCP.in, numbers)
                .and("iscurrentversion", QCP.equals, '1');
        DynamicObject[] attFileBases = BusinessDataServiceHelper.load("wtp_attfilebase", "id,org,attperson.id,attperson,attperson.number", attQF.toArray());
        //封装考勤档案对象
        Map<String,DynamicObject> attfileMap=new HashMap<>();
        for (DynamicObject attFileBase : attFileBases) {
            String attPersonNumber = attFileBase.getString("attperson.number");
            attfileMap.put(attPersonNumber,attFileBase);
        }

        DynamicObjectCollection query = QueryServiceHelper.query("nwg5_clockindevice", "nwg5_name,nwg5_number", null);
        StringBuffer doorIndex=new StringBuffer();
        for (DynamicObject single : query) {
            doorIndex.append(single.getString("nwg5_number"));
            doorIndex.append(",");
        }

        for (JSONArray jsonArray : requestJson) {
            ListValidator<PunchCardReqMode> listValidator=new ListValidator<>();
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject rowMap = jsonArray.getJSONObject(i);
                String cardNo = rowMap.getString("jobNo");
                if(cardNo == null){
                    continue;
                }
                //人员为找到考勤档案
                DynamicObject attFileBase = attfileMap.get(cardNo);
                if(attFileBase == null){
                    LOG.info("PunchcardDataUtil.getHAIKANPunchcardObtainList.attFileBase.人员为找到考勤档案，工号{}",cardNo);
                    continue;
                }

                String inAndOutType = rowMap.getString("inAndOutType");
                PunchCardReqMode punchCardReqMode=new PunchCardReqMode();

                punchCardReqMode.setDataId(rowMap.getString("eventId"));
                punchCardReqMode.setCard(cardNo);//考勤卡号
                punchCardReqMode.setNumber(cardNo);//工号

                String eventTime = rowMap.getString("eventTime");//产生时间

                String dateStrFromISO8601Timestamp = DateUtil.getDateStrFromISO8601Timestamp(eventTime);
                try{
                    Date parse = format.parse(dateStrFromISO8601Timestamp);
                    punchCardReqMode.setPunchCardDate(sdf.format(parse));//考勤日期
                    punchCardReqMode.setPunchCardTime(hms.format(parse));//考勤时间
                }catch (Exception e){
                    e.printStackTrace();
                    LOG.error("PunchcardDataUtil.getHAIKANPunchcardObtainList.e{}",e);
                    continue;
                }
                punchCardReqMode.setTimeZone("Asia/Shanghai");//时区
                String doorIndexCode = rowMap.getString("doorIndexCode");//门禁编码
                if(!doorIndex.toString().contains(doorIndexCode)) {
                    if ("1".equals(inAndOutType)) {
                        punchCardReqMode.setInout("on");//进卡
                    } else {
                        punchCardReqMode.setInout("off");//出卡
                    }
                }

                String doorName = rowMap.getString("doorName");//门禁名称
                String indexCode = rowMap.getString("doorRegionIndexCode");//门禁所在位置
                punchCardReqMode.setEquipNumber(doorIndexCode);//识别码
                punchCardReqMode.setEquipment(doorName);//打卡设备
                punchCardReqMode.setSignSource("接口同步");//打卡来源
                punchCardReqMode.setPlace(indexCode);//设备位置
                listValidator.add(punchCardReqMode);
            }
            list.add(listValidator);
        }
        return list;
    }


    /**
     * 发送飞书请求同步打卡数据
     * @return
     */
   public List<ListValidator<PunchCardReqMode>> getFSPunchcardObtainList(String startDate,String endDate){
       SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss");
       SimpleDateFormat form=new SimpleDateFormat("yyyy-MM-dd");
       List<ListValidator<PunchCardReqMode>> validatorlist = new ArrayList<>();
       ListValidator<PunchCardReqMode> records = new ListValidator<>();
       QFilter qFilter=new QFilter("iscurrentversion", QCP.equals,'1')
               .and(new QFilter("enable", QCP.equals,'1'))
               .and(new QFilter("status",QCP.equals,"C"));
       DynamicObject[] load = BusinessDataServiceHelper.load("wtp_attfilebase", "attperson", qFilter.toArray());
       List<List<String>> list=new ArrayList<>();
       List<String> userids=new ArrayList<>();
       //每五十条数据生成一个集合
       for (int i=0;i < load.length;i++) {
           DynamicObject attperson = load[i].getDynamicObject("attperson");
           userids.add(attperson.getString("number"));
           if(load.length-1 == i){
               list.add(userids);
           }else {
               if (userids.size() >= 50) {
                   list.add(userids);
                   userids = new ArrayList<>();
               }
           }
       }
       List<Map<String,Object>> fsClockRequest = requesUtil.getFSClockRequest(list,startDate,endDate);
       LOG.info("PunchcardDataUtil.getFSClockRequest.fsClockRequest:{}",fsClockRequest);
       for (Map<String, Object> rowMap : fsClockRequest) {
           Map data = (Map)rowMap.get("data");
           List<Map<String,Object>> userTaskResults = (List<Map<String,Object>> )data.get("user_task_results");
           for (Map<String, Object> taskResult : userTaskResults) {
               try {
                   if (records.size() >= 999) {
                       validatorlist.add(records);
                       records = new ListValidator<>();
                   }
                   String userNumber = taskResult.get("user_id").toString();
                  // Object day = taskResult.get("day");//年月日时间
                  // String mondayDate = getYearMondayDate(day.toString());
                   for (Map<String, Object> row : (List<Map<String, Object>>) taskResult.get("records")) {

                       Object inRecord = row.get("check_in_record");//上班卡数据
                       if (inRecord != null) {
                           Map inMap = (Map) inRecord;
                           inMap.get("check_time");//时间毫秒
                           PunchCardReqMode punchCardReqMode = new PunchCardReqMode();

                           punchCardReqMode.setDataId(inMap.get("record_id").toString());
                           punchCardReqMode.setCard(userNumber);//考勤卡号
                           punchCardReqMode.setNumber(userNumber);//工号
                           long checkTime = Long.parseLong(inMap.get("check_time").toString()) * 1000;
                           punchCardReqMode.setPunchCardDate(form.format(checkTime));//考勤日期

                           punchCardReqMode.setPunchCardTime(format.format(checkTime));//考勤时间
                           punchCardReqMode.setTimeZone("Asia/Shanghai");//时区
                           punchCardReqMode.setInout("on");//进出卡
                           punchCardReqMode.setEquipNumber("1001");//识别码
                           punchCardReqMode.setEquipment("飞书");//打卡设备
                           punchCardReqMode.setSignSource("接口同步");//打卡来源
                           punchCardReqMode.setPlace(inMap.get("location_name").toString());//设备位置
                           LOG.info("PunchcardDataUtil.getFSPunchcardObtainList.punchCardReqMode:{}",punchCardReqMode);
                           records.add(punchCardReqMode);
                       }
                       Object outRecord = row.get("check_out_record");//上班卡数据
                       if (outRecord != null) {
                           Map outMap = (Map) outRecord;
                           PunchCardReqMode punchCardReqMode = new PunchCardReqMode();

                           punchCardReqMode.setDataId(outMap.get("record_id").toString());
                           punchCardReqMode.setCard(userNumber);//考勤卡号
                           punchCardReqMode.setNumber(userNumber);//工号
                           long checkTime = Long.parseLong(outMap.get("check_time").toString())*1000;

                           punchCardReqMode.setPunchCardDate(form.format(checkTime));//考勤日期
                           punchCardReqMode.setPunchCardTime(format.format(checkTime));//考勤时间
                           punchCardReqMode.setTimeZone("Asia/Shanghai");//时区
                           punchCardReqMode.setInout("off");//进出卡
                           punchCardReqMode.setEquipNumber("1001");//识别码
                           punchCardReqMode.setEquipment("飞书");//打卡设备
                           punchCardReqMode.setSignSource("接口同步");//打卡来源
                           punchCardReqMode.setPlace(outMap.get("location_name").toString());//设备位置
                           LOG.info("PunchcardDataUtil.getFSPunchcardObtainList.punchCardReqMode:{}",punchCardReqMode);
                           records.add(punchCardReqMode);
                       }
                   }
               }catch (Exception e){
                   LOG.error("PunchcardDataUtil.getFSPunchcardObtainList.e{}",e);
               }
           }
       }
       validatorlist.add(records);
       return validatorlist;
   }

    /**
     * 根据毫秒获取时分秒
     * @param time 毫秒
     * @return
     */
   public static String getHourMinuteSecond(Long time){
       Calendar calendar=Calendar.getInstance();
       calendar.setTimeInMillis(time);
       int hour = calendar.get(Calendar.HOUR_OF_DAY);//时
       int minute = calendar.get(Calendar.MINUTE);//分
       int second = calendar.get(Calendar.SECOND);//秒
       StringBuffer dateStr=new StringBuffer();
       dateStr.append(hour);
       dateStr.append(":");
       dateStr.append(minute);
       dateStr.append(":");
       dateStr.append(second);
       return dateStr.toString();
   }

    /**
     * 时分秒格式获取
     * @param day  传入格式：20230912
     * @return     传出格式：2023-09-12
     */
   public static String getYearMondayDate(String day){
       SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
       SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
       try {
           Date parse = sdf.parse(day);
           return dateFormat.format(parse);
       }catch (Exception e){
           LOG.error("PunchcardDataUtil.getYearMondayDate.e:{}",e);
       }
       return null;
   }




}
